
package com.vanda.db.util;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.vanda.db.XQLData;
import com.vanda.db.cfg.MappingInfo;
import com.vanda.db.tag.LogicTag;
import com.vanda.util.Globals;
import com.vanda.util.LogFunc;


/**
 * XQL工具类<br>
 * 
 * @author 王瑛<br>
 * @version Version 1.00<br>
 */
public class XQLParser {
	/** 日志类 */
	private static Log log = LogFactory.getLog(XQLParser.class);
	
	/**
	 * 将xql配置文件解析成可以执行的xql及参数集
	 * @param info xql配置文件类
	 * @param objs xql参数类
	 * @return
	 * @throws Exception
	 */
	public static XQLData[] parse(MappingInfo info, Object[] objs) throws Exception {
		StringBuffer xqlBuffer = new StringBuffer();
		
		List lstContent = info.getContent();
		XQLData[] datas = new XQLData[lstContent.size()];
		
		LogicTag logicTag = new LogicTag();
		HashMap params = getParams(info,objs);
		
		for(int i=0;i<lstContent.size();i++){
			logicTag.setContent((String)lstContent.get(i));
			logicTag.setParams(params);
			
			datas[i] = logicTag.parse();
			printInfo(info,datas[i]);
		}

		return datas;
	}
	
	/**
	 * 将xql配置文件解析成可以执行的CountXql(取得记录总数的xql)及参数集
	 * @param info xql配置文件类
	 * @param objs xql参数类
	 * @return
	 * @throws Exception
	 */
	public static XQLData parseCountXQL(MappingInfo info,Object[] objs) throws Exception{
		if(info.getCountXQL() == null || info.getCountXQL().trim().length() == 0){
			return null;
		}
		StringBuffer xqlBuffer = new StringBuffer();
		
		List lstContent = info.getContent();
		XQLData data = new XQLData();
		
		LogicTag logicTag = new LogicTag();
		HashMap params = getParams(info,objs);
		
		
		logicTag.setContent(info.getCountXQL());
		logicTag.setParams(params);
			
		data = logicTag.parse();
		
		printInfo(info,data);
		
		return data;
	}
	
	/**
	 * 打印xql
	 * @param info
	 * @param data
	 */
	private static void printInfo(MappingInfo info,XQLData data){
		int level = Globals.getIntValue("log.level");
		//如果level大于0，则不打印
		if(level > 0){
			return;
		}
		
		StringBuffer buffer = new StringBuffer("\nXQL Name = "+info.getName());
		if(info.getReturnClass() != null){
			buffer.append("\nXQL returnClass = ").append(info.getReturnClass());
		}
		buffer.append("\n");
		buffer.append("XQL Content = ").append(data.getXql());
		buffer.append("\n");
		buffer.append("XQL Params = "+data.getValues()).append("\n");
		LogFunc.info(buffer.toString());
	}
	
	/**
	 * 取得参数别名与参数类的对应关系
	 * @param info xql配置文件类
	 * @param objs 参数类
	 * @return
	 */
	private static HashMap getParams(MappingInfo info, Object[] objs){
		HashMap params = new HashMap();
		
		HashMap clsParams = info.getParams();
		
		//取得key值
		Iterator iter = clsParams.keySet().iterator();
		while(iter.hasNext()){
			String key = (String)iter.next();
			String clsName = (String)clsParams.get(key);
			
			for(int i=0;i<objs.length;i++){
				if(clsName.equals(objs[i].getClass().getName())){
					params.put(key,objs[i]);
					break;
				}
			}
		}
		
		return params;	
	}
	
	/**
	 * 取得xql对应的查询记录总数的xql
	 * @param xql 
	 * @return
	 */
	public static String getCountXQL(String xql){
		
		//根据sql得到对应的查询记录总数的sql
		String countXql = new String("select count(*) ");
		String queryClone = new String(xql);
		queryClone = queryClone.toLowerCase();
		int pos = queryClone.indexOf("from");
		int offset = 0;
		
		while(pos >= 0){
			
			char first = ' ';
			char last = ' ';
			if(pos > 0){
				first = queryClone.charAt(pos-1);
			}
			if(pos + 4 < queryClone.length()){
				last = queryClone.charAt(pos + 4);
			}
			if(DBUtils.isEmptyChar(first) && DBUtils.isEmptyChar(last)){
				break;
			}
			queryClone = queryClone.substring(pos+4);
			offset += pos+4;
			pos = queryClone.indexOf("from");
		}
		
		if (pos >= 0) {
			pos += offset;

			countXql += xql.substring(pos, xql.length());
		}
		
		return countXql;
	}
	
	public static void main(String[] args){
		String str = "select a.from,bfrom,cfrom from a where a.afrom = 1";
		//String str = "select afrom,bfrom\n"+"from\n"+"a where a.from = 1";
		//String str = "from a where a.from = 1";
		
		System.out.println("count sql = "+getCountXQL(str));
	}
}
